Skip to content

Conversation

@ktoso
Copy link
Contributor

@ktoso ktoso commented Nov 21, 2025

Introduce a proposal for task cancellation shields to allow certain code to execute regardless of task cancellation status.

Implementation WIP PR: swiftlang/swift#85637

Introduce a proposal for task cancellation shields to allow certain code to execute regardless of task cancellation status.

Implementation WIP PR: swiftlang/swift#85637
Updated reference to SE-0493 to include a link.
Comment on lines +76 to +84
public func withTaskCancellationShield<T, E>(
_ operation: () throws(E) -> T,
file: String = #fileID, line: Int = #line
) throws(E) -> T

public nonisolated(nonsending) func withTaskCancellationShield<T, E>(
_ operation: nonisolated(nonsending) () async throws(E) -> T, // FIXME: order of attrs
file: String = #fileID, line: Int = #line
) async throws(E) -> T
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we give the generic types a slightly more descriptive name so it shows up nicely in the docs. On the PR that introduced nonisolated(nonsending) to the withTaskCancellationHandler methods we used Return and Failure for those two generic types.

Suggested change
public func withTaskCancellationShield<T, E>(
_ operation: () throws(E) -> T,
file: String = #fileID, line: Int = #line
) throws(E) -> T
public nonisolated(nonsending) func withTaskCancellationShield<T, E>(
_ operation: nonisolated(nonsending) () async throws(E) -> T, // FIXME: order of attrs
file: String = #fileID, line: Int = #line
) async throws(E) -> T
public func withTaskCancellationShield<Result, Failure>(
_ operation: () throws(Failure) -> Result,
file: String = #fileID, line: Int = #line
) throws(Failure) -> Result
public nonisolated(nonsending) func withTaskCancellationShield<Result, Failure>(
_ operation: nonisolated(nonsending) () async throws(Failure) -> Result, // FIXME: order of attrs
file: String = #fileID, line: Int = #line
) async throws(Failure) -> Result

await withTaskCancellationShield {
await withDiscardingTaskGroup { group in
group.addTask { ... }
group.cancelAll() // cancels all tasks within the group, as expected
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is perfect and exactly how I expected it.


func cleanup() {
withTaskCancellationShield {

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this missing a slowOperation call here?


```swift
extension Task where Success == Never, Failure == Never {
public static func isCancelled(ignoringCancellationShield: Bool) -> Bool
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 I think that's great for debugging purposes


## Motivation

Task cancellation is _final_ and can not be ignored or undone. Once a task has been cancelled, it remains cancelled for the rest of its existance.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Task cancellation is _final_ and can not be ignored or undone. Once a task has been cancelled, it remains cancelled for the rest of its existance.
Task cancellation is _final_ and can not be ignored or undone. Once a task has been cancelled, it remains cancelled for the rest of its existence.


Doing nothing is always an option, and we suggest developers have to keep using the unstructured task workaround.

This doesn't seem viable though as the problem indeed is real, and the workaround is problematic scheduling wise, and may not even be usable in certain situations.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

may not even be usable in certain situations

is the only example of this the synchronous context case cited above, or are there others?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants